{
 "cells": [
  {
   "cell_type": "code",
   "id": "initial_id",
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2025-04-08T10:20:58.868317Z",
     "start_time": "2025-04-08T10:20:47.993257Z"
    }
   },
   "source": [
    "#导包\n",
    "import time\n",
    "import numpy as np\n",
    "from sklearn.datasets import fetch_openml\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.linear_model import Perceptron, LogisticRegression\n",
    "from sklearn.neural_network import MLPClassifier\n",
    "from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score, confusion_matrix\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.optim as optim\n",
    "from torchvision import datasets, transforms\n",
    "from torch.utils.data import DataLoader"
   ],
   "outputs": [],
   "execution_count": 1
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-08T10:21:08.017054Z",
     "start_time": "2025-04-08T10:21:00.865174Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 加载MNIST数据集\n",
    "mnist = fetch_openml('mnist_784', version=1, cache=True)\n",
    "X = mnist.data / 255.0  # 归一化处理\n",
    "y = mnist.target.astype(int)"
   ],
   "id": "f59bc9b4d7bd311b",
   "outputs": [],
   "execution_count": 2
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-08T10:21:14.279591Z",
     "start_time": "2025-04-08T10:21:13.390574Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 划分训练集和测试集\n",
    "X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)"
   ],
   "id": "6799353cf513938b",
   "outputs": [],
   "execution_count": 3
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-08T10:21:26.477819Z",
     "start_time": "2025-04-08T10:21:26.471374Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 定义评估函数\n",
    "def evaluate_model(model, X_test, y_test):\n",
    "    y_pred = model.predict(X_test)\n",
    "    accuracy = accuracy_score(y_test, y_pred)\n",
    "    precision = precision_score(y_test, y_pred, average='weighted')\n",
    "    recall = recall_score(y_test, y_pred, average='weighted')\n",
    "    f1 = f1_score(y_test, y_pred, average='weighted')\n",
    "    conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "    return accuracy, precision, recall, f1, conf_matrix"
   ],
   "id": "9efe3b425bcbbd84",
   "outputs": [],
   "execution_count": 4
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-08T10:21:55.101590Z",
     "start_time": "2025-04-08T10:21:46.088299Z"
    }
   },
   "cell_type": "code",
   "source": [
    "# 自主实现感知机模型\n",
    "class PerceptronModel:\n",
    "    def __init__(self, input_size, num_classes, learning_rate=0.01, epochs=10):\n",
    "        self.weights = np.zeros((num_classes, input_size))\n",
    "        self.bias = np.zeros(num_classes)\n",
    "        self.learning_rate = learning_rate\n",
    "        self.epochs = epochs\n",
    "\n",
    "    def train(self, X, y):\n",
    "        for epoch in range(self.epochs):\n",
    "            for i in range(X.shape[0]):\n",
    "                xi = X[i]\n",
    "                yi = y[i]\n",
    "                scores = np.dot(self.weights, xi) + self.bias\n",
    "                predicted_class = np.argmax(scores)\n",
    "                if predicted_class != yi:\n",
    "                    self.weights[yi] += self.learning_rate * xi\n",
    "                    self.bias[yi] += self.learning_rate\n",
    "                    self.weights[predicted_class] -= self.learning_rate * xi\n",
    "                    self.bias[predicted_class] -= self.learning_rate\n",
    "\n",
    "    def predict(self, X):\n",
    "        scores = np.dot(X, self.weights.T) + self.bias\n",
    "        return np.argmax(scores, axis=1)\n",
    "\n",
    "# 初始化感知机模型\n",
    "input_size = X_train.shape[1]\n",
    "num_classes = len(np.unique(y_train))\n",
    "perceptron_model = PerceptronModel(input_size, num_classes, learning_rate=0.01, epochs=10)\n",
    "\n",
    "# 训练模型\n",
    "start_time = time.time()\n",
    "perceptron_model.train(X_train.to_numpy(), y_train.to_numpy())\n",
    "training_time = time.time() - start_time\n",
    "\n",
    "# 测试模型\n",
    "y_pred = perceptron_model.predict(X_test.to_numpy())\n",
    "\n",
    "# 计算评估指标\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "precision = precision_score(y_test, y_pred, average='weighted')\n",
    "recall = recall_score(y_test, y_pred, average='weighted')\n",
    "f1 = f1_score(y_test, y_pred, average='weighted')\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "\n",
    "# 输出结果\n",
    "print(\"自主实现感知机模型：\")\n",
    "print(f\"准确率: {accuracy}\")\n",
    "print(f\"精确率: {precision}\")\n",
    "print(f\"召回率: {recall}\")\n",
    "print(f\"F1分数: {f1}\")\n",
    "print(f\"混淆矩阵:\\n{conf_matrix}\")\n",
    "print(f\"训练时间: {training_time} 秒\")"
   ],
   "id": "4528a7b29de79bce",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "自主实现感知机模型：\n",
      "准确率: 0.855904761904762\n",
      "精确率: 0.8720308940948863\n",
      "召回率: 0.855904761904762\n",
      "F1分数: 0.856309547104941\n",
      "混淆矩阵:\n",
      "[[1948    1    8    6    2   28   51    8    6    0]\n",
      " [   0 2184    5  116    2   18   18   10   11    0]\n",
      " [  14   16 1545  275   10   11  138   32   86    6]\n",
      " [   9    3   12 2032    1   44   18   18   32    7]\n",
      " [   7    5   13   28 1583    6  155   30   49   60]\n",
      " [  21   10    6  152   12 1545  111   10   44    4]\n",
      " [   6    0    8    4    5   15 2042    5    3    0]\n",
      " [  13    3   12   40   13   16    0 2123   12   16]\n",
      " [   9   22    8  303    5   59  101    9 1467    9]\n",
      " [  20    7    9   91   35   31   20  286   86 1505]]\n",
      "训练时间: 8.839531421661377 秒\n"
     ]
    }
   ],
   "execution_count": 5
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-08T10:22:16.651746Z",
     "start_time": "2025-04-08T10:22:14.094775Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class LogisticRegressionModel:\n",
    "    def __init__(self, input_size, num_classes, learning_rate=0.01, epochs=10):\n",
    "        self.weights = np.zeros((num_classes, input_size))\n",
    "        self.bias = np.zeros(num_classes)\n",
    "        self.learning_rate = learning_rate\n",
    "        self.epochs = epochs\n",
    "\n",
    "    def softmax(self, z):\n",
    "        exp_z = np.exp(z - np.max(z, axis=1, keepdims=True))\n",
    "        return exp_z / np.sum(exp_z, axis=1, keepdims=True)\n",
    "\n",
    "    def train(self, X, y):\n",
    "        y_one_hot = np.eye(self.weights.shape[0])[y]\n",
    "        for epoch in range(self.epochs):\n",
    "            scores = np.dot(X, self.weights.T) + self.bias\n",
    "            probs = self.softmax(scores)\n",
    "            gradient_w = np.dot((probs - y_one_hot).T, X) / X.shape[0]\n",
    "            gradient_b = np.mean(probs - y_one_hot, axis=0)\n",
    "            self.weights -= self.learning_rate * gradient_w\n",
    "            self.bias -= self.learning_rate * gradient_b\n",
    "\n",
    "    def predict(self, X):\n",
    "        scores = np.dot(X, self.weights.T) + self.bias\n",
    "        probs = self.softmax(scores)\n",
    "        return np.argmax(probs, axis=1)\n",
    "\n",
    "# 初始化Logistic回归模型\n",
    "logistic_model = LogisticRegressionModel(input_size=X_train.shape[1], num_classes=len(np.unique(y_train)), learning_rate=0.01, epochs=10)\n",
    "\n",
    "# 训练模型\n",
    "start_time = time.time()\n",
    "logistic_model.train(X_train.to_numpy(), y_train.to_numpy())\n",
    "training_time = time.time() - start_time\n",
    "\n",
    "# 测试模型\n",
    "y_pred = logistic_model.predict(X_test.to_numpy())\n",
    "\n",
    "# 计算评估指标\n",
    "accuracy = accuracy_score(y_test, y_pred)\n",
    "precision = precision_score(y_test, y_pred, average='weighted')\n",
    "recall = recall_score(y_test, y_pred, average='weighted')\n",
    "f1 = f1_score(y_test, y_pred, average='weighted')\n",
    "conf_matrix = confusion_matrix(y_test, y_pred)\n",
    "\n",
    "# 输出结果\n",
    "print(\"自主实现Logistic回归模型：\")\n",
    "print(f\"准确率: {accuracy}\")\n",
    "print(f\"精确率: {precision}\")\n",
    "print(f\"召回率: {recall}\")\n",
    "print(f\"F1分数: {f1}\")\n",
    "print(f\"混淆矩阵:\\n{conf_matrix}\")\n",
    "print(f\"训练时间: {training_time} 秒\")"
   ],
   "id": "2656acafe04ba3e9",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "自主实现Logistic回归模型：\n",
      "准确率: 0.7080952380952381\n",
      "精确率: 0.708806743812748\n",
      "召回率: 0.7080952380952381\n",
      "F1分数: 0.6880524431743219\n",
      "混淆矩阵:\n",
      "[[2015    0    4    3    0    0   11    0   25    0]\n",
      " [   5 1967    5   37    1    0    3    1  343    2]\n",
      " [ 224   17 1505  104    8    0   89   14  164    8]\n",
      " [ 156    5   42 1744    0    0   11   13  195   10]\n",
      " [ 130    6   15   21 1167    0   58    4  242  293]\n",
      " [ 793   10   29  440    9    0   26    4  582   22]\n",
      " [ 238   14   44    9    3    0 1713    0   67    0]\n",
      " [ 166   29   30   20    9    0    2 1709  192   91]\n",
      " [ 118    6   10  166    1    0   13    3 1662   13]\n",
      " [ 167    5   26   46   48    0    1   58  351 1388]]\n",
      "训练时间: 2.4817566871643066 秒\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "E:\\Ruanjian\\Python\\anacondn\\envs\\jinke\\Lib\\site-packages\\sklearn\\metrics\\_classification.py:1565: UndefinedMetricWarning: Precision is ill-defined and being set to 0.0 in labels with no predicted samples. Use `zero_division` parameter to control this behavior.\n",
      "  _warn_prf(average, modifier, f\"{metric.capitalize()} is\", len(result))\n"
     ]
    }
   ],
   "execution_count": 6
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-04-08T11:49:08.433525Z",
     "start_time": "2025-04-08T11:49:08.426529Z"
    }
   },
   "cell_type": "code",
   "source": "print(\"a\")",
   "id": "9ae632c243001ca9",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "a\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "e02ce3e64305aa3f"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}